#ifndef __XTCSTRATEGIES_H_INCLUDED
#define __XTCSTRATEGIES_H_INCLUDED

int MIN(int a, int b)
{
  if (a < b) return a;
  else return b;
}

int MAX(int a, int b)
{
  if (a > b) return a;
  else return b;
}

stratego code makereg(code body)
{
  strategies
    main = topdown(try(MakeReg))

  rules
    MakeReg:
      TypeSpec(p, _, _) -> TypeSpec(p, TypeId("reg"), [])
}

stratego code getlocals(code larr, code body)
{
  imports
    analyse-locality

  strategies
    main =
      ?(larr, body);
      !larr; \ArrayInit(a) -> a\; map(\AssignInit(CodeConst(a)) -> a\); ?locals;
      !(locals, body); analyse-locality; ?(newlocals, newbody); !newlocals;
      map(\a -> AssignInit(CodeConst(a))\); \a -> ArrayInit(a)\; id
}

stratego code makelmem(code locals, code body)
{
  imports
    sc-rules
    sc-strategies

  strategies
    main =
      ?(locals, body); 
      !locals; \ArrayInit(a) -> a\; map(\AssignInit(CodeConst(a)) -> a\); ?localids;
      !(body, localids); env-seq(try(env-alltd(MakeLMem))); bottomup(try(apply-conc))

  rules
    MakeLMem:
      (Declaration2(_, [iddecl]), i) ->
      Declaration2(TypeSpec([], TypeId("lmem"), []), [iddecl])
      where (<get-id>(iddecl) => i)
}

#ifdef MERGE
void __SEPARATOR__(void);
void linebyline(argcode_t *args, int arguments, code prologue, code body, code epilogue)
{
  __SEPARATOR__();

  @prologue;

  __SEPARATOR__();

  @body;

  __SEPARATOR__();

  @epilogue;

  __SEPARATOR__();
}
#else
void linebyline(argcode_t *_argcode, int _arguments, code _prologue, code _body, code _epilogue)
{
  int __ii;

  @_body;

  /* Set properties */
  propEnvReset();
  propEnv("operation", operation);
 
  for (__ii=0; __ii < _arguments; __ii++)
  {
    propEnv("argument", @idtostring(makeid(`id`, __ii)));
      propSeti("id", __ii);
      propEnv("target", target);

      propSeti("buffer", _argcode[__ii].state.buffer);
      propSeti("state", _argcode[__ii].state.state);
      propSeti("delay", _argcode[__ii].state.delay);

      propSeti("elementsize", sizeof(_argcode[__ii].datatype));

      if (_argcode[__ii].argtype == ARG_STREAM_IN || _argcode[__ii].argtype == ARG_STREAM_OUT)
        propSeti("chunksize", 1024);
      else
        propSeti("chunksize", 1);

      propSets("timedist", "regular");

      propEnvBack();
    propEnvBack();
  }
}
#endif

#endif /* __XTCSTRATEGIES_H_INCLUDED */
